package com.zzl.alligator.framework.job.listener;

import com.zzl.alligator.common.constant.Constants;
import com.zzl.alligator.common.util.SpringUtils;
import com.zzl.alligator.framework.async.AsyncManager;
import com.zzl.alligator.management.monitor.domain.SysJobLog;
import com.zzl.alligator.management.monitor.service.impl.SysJobLogService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.JobListener;

import java.util.TimerTask;

/**
 * TODO
 *
 * @author zhouziliang
 * @since 2020/7/11
 */
@Slf4j
public class JobLogListener implements JobListener {
    /**
     * <p>
     * Get the name of the <code>JobListener</code>.
     * </p>
     */
    @Override
    public String getName() {
        String name = getClass().getSimpleName();
        return name;
    }

    /**
     * <p>
     * Called by the <code>{@link Scheduler}</code> when a <code>{@link JobDetail}</code>
     * is about to be executed (an associated <code>{@link Trigger}</code>
     * has occurred).
     * </p>
     *
     * <p>
     * This method will not be invoked if the execution of the Job was vetoed
     * by a <code>{@link TriggerListener}</code>.
     * </p>
     *
     * @param context
     * @see #jobExecutionVetoed(JobExecutionContext)
     */
    @Override
    public void jobToBeExecuted(JobExecutionContext context) {

    }

    /**
     * <p>
     * Called by the <code>{@link Scheduler}</code> when a <code>{@link JobDetail}</code>
     * was about to be executed (an associated <code>{@link Trigger}</code>
     * has occurred), but a <code>{@link TriggerListener}</code> vetoed it's
     * execution.
     * </p>
     *
     * @param context
     * @see #jobToBeExecuted(JobExecutionContext)
     */
    @Override
    public void jobExecutionVetoed(JobExecutionContext context) {

    }

    /**
     * <p>
     * Called by the <code>{@link Scheduler}</code> after a <code>{@link JobDetail}</code>
     * has been executed, and be for the associated <code>Trigger</code>'s
     * <code>triggered(xx)</code> method has been called.
     * </p>
     *
     * @param context
     * @param jobException
     */
    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        final SysJobLog jobLog = getJobLog(context, jobException, Constants.SUCCESS);
        AsyncManager.me().execute(new TimerTask() {
            @Override
            public void run() {
                SysJobLogService service = SpringUtils.getBean(SysJobLogService.class);
                service.insertSysJobLog(jobLog);
            }
        });
    }

    private SysJobLog getJobLog(JobExecutionContext context, JobExecutionException jobException, String success) {
        SysJobLog jobLog = new SysJobLog();
        JobKey key = context.getJobDetail().getKey();
        jobLog.setJobName(key.getName());
        jobLog.setJobGroup(key.getGroup());
        if (jobException != null) {
            jobLog.setExceptionInfo(jobException.getMessage());
        }
        jobLog.setJobClassName(context.getJobDetail().getJobClass().getName());
        jobLog.setJobMethodName(context.getJobDetail().getJobDataMap().getString("jobMethodName"));
        jobLog.setStatus(success);
        return jobLog;
    }
}
